package ch.zbw.iCoach.Dameon;
/**
 *  This class works as with the main logic interface classs to import and export data.
 *  only CSV data that is supported by this class.
 *  Information for Users and Languages are stored in the respective CVS files.  
 *  .This class requires access to the reference library  opencsv-1.8.jar
 * 
 * @author Dameon Crane
 * @version Version 1 (release 18.03.2013)
 */
import au.com.bytecode.opencsv.*;
import ch.zbw.iCoach.remo.*;

import java.io.*;
import java.util.*;
/**
	* The constructor holds a lot of parameters. 
	* It requires two class instances, one from LanguageList and another form UserList 
	* 
	* 
	* 
	* the both int value are both initialized with "-1". this is again useful for support investigation.
	* 
	* @param languageList	A reference of an actual LanguageList
	* @param UserList    	A reference of an actual UserList
	* @param readerDE		reader name for German
	* @param readerEN		reader name for English
	* @param readerFR		reader name for French
	* @param readerIT		reader name for Italian
	* @param readerLang		reader name for importing user languages
	* @param readerUser		reader name for importing existing users
	* @param firstname		The first name form the playing user
	* @param username		The user name form the playing user
	* @param writerLang		writer name for exporting languages
	* @param writerUser 	writer name for exporting users
	* @param wordLang		String Array for importing user languages
	* @param wordDE	        String Array for importing German
	* @param wordEN	        String Array for importing English
	* @param wordFR	        String Array for importing French
	* @param wordIT	        String Array for importing Italian
	* @param userName		String Array for importing users
	* @param CsvPath		Default path for import and export of data (relative path to the bin dir.
	* @param LangFileDE		FIle name for German
	* @param LangFileEN		FIle name for English
	* @param LangFileFR		FIle name for French
	* @param LangFileIT		FIle name for Italian
	* @param LangFile		FIle name for user specific languages
	* @param UserFile		FIle name for multiple users
	* @param nameUser		parameter to export user names
	*/
public class DataHandlingIO {

	LanguageList  myLang;
	UserList myUL;
	CSVReader readerDE;
	CSVReader readerEN;
	CSVReader readerFR;
	CSVReader readerIT;
	CSVReader readerLang;
	CSVReader readerUser;

	CSVWriter writerLang;
	CSVWriter writerUser;

	String[] wordLang;
	String[] wordDE;
	String[] wordEN;
	String[] wordFR;
	String[] wordIT;
	String[] userName;
	

	String CsvPath = "./bin/";
	String LangFileDE = "#DE.CSV";
	String LangFileEN = "#EN.CSV";
	String LangFileFR = "#FR.CSV";
	String LangFileIT = "#IT.CSV";
	String LangFile = "Library.csv";
	String UserFile = "User.CSV";
	String nameUser;

	public DataHandlingIO(LanguageList languageList, UserList userList ) {
		this.myLang = languageList;
		this.myUL = userList;
	}
	/**
	* This method imports the standard language from csv's
	* 
	*/
	public boolean startUp(String userName) {
		boolean errorIO = false;

		try {
			int langID, priKeyDE, parKeyDE, priKeyEN, parKeyEN, priKeyFR, parKeyFR, priKeyIT, parKeyIT; 
	           
            /**
			*Load CSV files
			*
            */
            readerDE = new CSVReader(new FileReader(CsvPath + LangFileDE));
            readerEN = new CSVReader(new FileReader(CsvPath + LangFileEN));
            readerFR = new CSVReader(new FileReader(CsvPath + LangFileFR));
            readerIT = new CSVReader(new FileReader(CsvPath + LangFileIT));
            
            /**
			*Do not read the headers
			*
            */
            wordDE = readerDE.readNext();
            wordEN = readerEN.readNext();
            wordFR = readerFR.readNext();
            wordIT = readerIT.readNext();
            
            /**
			*Empty any existing language arrays
			*
            */
            myLang.clearAllData();
            
            while ((wordDE = readerDE.readNext()) != null)
            {
            	/**
            	 *Add German to the language array
            	 *
            	 */
            	langID = Integer.parseInt(wordDE[0].trim());
                priKeyDE = Integer.parseInt(wordDE[1].trim());
                parKeyDE = Integer.parseInt(wordDE[2].trim());
                myLang.createLanguage(new Language (wordDE[3],langID, priKeyDE, parKeyDE,userName));

            }
	            
	            while ((wordEN = readerEN.readNext()) != null)
	            {
	            	/**
	            	 *Add English to the language array
	            	 *
	            	 */
	            	langID = Integer.parseInt(wordEN[0].trim());
	                priKeyEN = Integer.parseInt(wordEN[1].trim());
	                parKeyEN = Integer.parseInt(wordEN[2].trim());
	                myLang.createLanguage(new Language (wordEN[3],langID, priKeyEN, parKeyEN,userName));
	            }
	            
	            while ((wordFR = readerFR.readNext()) != null)
	            {
	            	/**
	            	 *Add French to the language array
	            	 *
	            	 */
	            	langID = Integer.parseInt(wordFR[0].trim());
	                priKeyFR = Integer.parseInt(wordFR[1].trim());
	                parKeyFR = Integer.parseInt(wordFR[2].trim());
	                myLang.createLanguage(new Language (wordFR[3],langID, priKeyFR, parKeyFR,userName));
	            }
	            
	            while ((wordIT = readerIT.readNext()) != null)
	            {
	            	/**
	            	 *Add Italian to the language array
	            	 *
	            	 */
	            	langID = Integer.parseInt(wordIT[0].trim());
	                priKeyIT = Integer.parseInt(wordIT[1].trim());
	                parKeyIT = Integer.parseInt(wordIT[2].trim());
	                myLang.createLanguage(new Language(wordIT[3],langID, priKeyIT, parKeyIT,userName));
	            }
	        }
        	/**
        	 *Catch any exception thrown from FileNotFound
        	 *
        	 */
			catch ( FileNotFoundException e )
			{
				//System.err.println( "Files are not found: no users available. Please create a new user" );
				errorIO = true;				
			}
    		/**
    		 *Catch any exception thrown from IO
    		 *
    		*/
	        catch(IOException e)
	        {
	           //System.out.println("IOException: ");
	          //  e.printStackTrace();
	            errorIO = true;
	        }		
		        return errorIO;
	    }
	
	/**
	* This method imports the user specific language
	* 
	*/

	public boolean importLang() {
		
		boolean errorIO = false;

		try {
			int langID, priKeyLang, parKeyLang, word;

            /**
			*Load CSV files
			*
            */
			readerLang = new CSVReader(new FileReader(CsvPath + LangFile));

            /**
			*Do not read the headers
			*
            */
			
			wordLang = readerLang.readNext();
			
            /**
			*Empty any existing language arrays
			*
            */

			myLang.clearAllData();

			while ((wordLang = readerLang.readNext()) != null) {
	            /**
				*Create a new Language Array
				*
	            */
				langID = Integer.parseInt(wordLang[0].trim());
				priKeyLang = Integer.parseInt(wordLang[1].trim());
				parKeyLang = Integer.parseInt(wordLang[2].trim());
				 myLang.createLanguage(new Language(wordLang[3],langID, priKeyLang, parKeyLang,nameUser));
			}
		}
		
		catch ( FileNotFoundException e )
		{
			/**
    		 *Catch any exception thrown from FIleNotFOund
    		 *
    		*/
	            errorIO = true;				
		}

		catch (IOException e) {
			/**
    		 *Catch any exception thrown from IO
    		 *
    		*/
			errorIO = true;
		}
		return errorIO;

	}

	/**
	* This method exports/saves the user language
	* 
	*/
	public boolean exportLang(LanguageList mylang)
	    {
			this.myLang = mylang;
	        boolean errorIO = false;
	        
	        try
	        {
	        	/**
	    		 *Create a new CSV file
	    		 *
	    		*/
	            writerLang = new CSVWriter(new FileWriter(CsvPath+LangFile));
	            
	            
	            
	            String[] entriesLang = new String[mylang.getSize()];
	            entriesLang = "LANGID#PRIMARY_KEY#PARENT_KEY#WORD#USER".split("#");
	        	/**
	    		 *Create a the header in the new CSV file
	    		 *initialise the String Array
	    		*/
	                       
	            
	            for(int i = 0; i < mylang.getSize(); i++){
	            {
	            	Language tempLang = mylang.getlang(i);
	            	
	            	entriesLang = (tempLang.getLangID()+ "#" + tempLang.getPrimaryKey()+ "#" + tempLang.getParentKey()+ "#" +tempLang.getWord() + "#" + tempLang.getUserName()).split("#");
	            		        }
	            writerLang.writeNext(entriesLang);
	            
	            }
	            writerLang.close(); 
	        }
	        /**
    		 *Catch any exception thrown from IO
    		 *
    		*/
	            catch(IOException e)
	        {
	            //System.out.println("IOException: ");
	            //e.printStackTrace();
	            errorIO = true;
	        }
	        
	        return errorIO;
	    }
	/**
	* This method exports the active user names
	* 
	*/
	public boolean exportUser(UserList myUL)
    {
        boolean errorIO = false;
        
        try
        {
        	/**
    		 *Create a new CSV file
    		 *
    		*/
                       
            writerUser = new CSVWriter(new FileWriter(CsvPath+UserFile));
            
            /**
    		 *Create a the header in the new CSV file
    		 *initialise the String Array
    		*/
            String[] entriesUser = new String[myUL.getSize()];
            entriesUser = "firstName#lastName#userName".split("#");
            
            for(int i = 0; i < myUL.getSize(); i++){
	            {
	            	User tempUser = myUL.getUser(i);
	            	
	            	entriesUser = (tempUser.getFirstname()+ "#" + tempUser.getLastname()+ "#" + tempUser.getUsername()).split("#");
	            		        }
	            writerUser.writeNext(entriesUser);
	            
	            }
           
            writerUser.close(); 
        }
        /**
		 *Catch any exception thrown from IO
		 *
		*/
        catch(IOException e)
        {
            System.out.println("IOException: ");
            //e.printStackTrace();
            errorIO = true;
        }
        return errorIO;
    }
	
	/**
	* This method imports any user saved at teh last exit of the program
	* 
	*/
public boolean importUser() {
		
		boolean errorIO = false;

		try {
			
			/**
			*Load CSV files
			*
            */
			readerUser = new CSVReader(new FileReader(CsvPath + UserFile));

			// 'delete' the header rows
			//userName = readerUser.readNext();

			while ((userName = readerUser.readNext()) != null) {
				// create Languages
				 myUL.addUser(new User(userName[0],userName[1], userName[2]));
			}
		}
		/**
		 *Catch any exception thrown from FIleNotFOund
		 *
		 */
		catch ( FileNotFoundException e )
		{
			//System.err.println( "Files are not found: Start a new game" );
			 //e.printStackTrace();
	            errorIO = true;				
		}
		/**
		 *Catch any exception thrown from IO
		 *
		 */
		catch (IOException e) {
			//System.out.println("IOException: ");
			//e.printStackTrace();
			errorIO = true;
		}
		return errorIO;

	}

/**
* This method reorders the primary keys when adding a new word.
* 
*/
	
	
	public int generateNewLangPriKey() {
		int priKeyLang = myLang.getSize();
		int tempPriKeyLang = priKeyLang;
		boolean PriKeyLangNotExist = true;
		boolean PriKeyLangNotExistControl = false;
		
		for (int i = 0; i < myLang.getSize(); i++){
			Language tempLang = myLang.getlang(i);
			if (tempLang.getParentKey() == tempPriKeyLang){
				PriKeyLangNotExist = false;
			}
		}
		if (PriKeyLangNotExist == true){
			return tempPriKeyLang;
		}
		
		if (PriKeyLangNotExist == false){
			PriKeyLangNotExist = true;
			while(PriKeyLangNotExistControl == false){
				tempPriKeyLang ++;
				for (int i = 0; i < myLang.getSize(); i++){
					Language tempLang = myLang.getlang(i);
					if (tempLang.getParentKey() == tempPriKeyLang){
						PriKeyLangNotExist = false;
					}
				}
				if (PriKeyLangNotExist == true){
					PriKeyLangNotExistControl = true;
				}
			}
		}
	return tempPriKeyLang;
	}
}